home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / Shareware Internet / Desarrolladores / PlayerPRO 4.5.1 Dev.Kit / Plug-Ins / Filters Plugs / Mix.c < prev    next >
C/C++ Source or Header  |  1995-10-08  |  9KB  |  345 lines

  1. /*    Mix                */
  2. /*    v 0.2            */
  3. /*    1995 by Liane    */
  4.  
  5. //    Usage:
  6. //    Digital mixing of two sounds.
  7. //    The sound in the clipboard (get it by Copy) is
  8. //    mixed with the one opened, beginning at the
  9. //    start of the selection.
  10. //    The sound is extended as needed, and Normalize
  11. //    is applied to avoid clipping.
  12. //
  13. //    WARNING
  14. //    This plug does work ONLY with 8 bits data
  15.  
  16. #include <A4Stuff.h>
  17. #include <SetUpA4.h>
  18. #include <Sound.h>
  19. #include "MAD.h"
  20. #include "PPPlug.h"
  21.  
  22. #if defined(powerc) || defined(__powerc)
  23. enum {
  24.         PlayerPROPlug = kCStackBased
  25.         | RESULT_SIZE(SIZE_CODE( sizeof(OSErr)))
  26.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( sData*)))
  27.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( long)))
  28.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( long)))
  29.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoPlug*)))
  30. };
  31.  
  32. ProcInfoType __procinfo = PlayerPROPlug;
  33. #else
  34. #include <A4Stuff.h>
  35. #endif
  36.  
  37.  
  38. typedef short    *shortPtr;
  39. typedef long    *longPtr;
  40.  
  41. #define enclosure    9
  42. #define sname1        3
  43. #define sname2        4
  44. #define slider1        5
  45. #define slider2        6
  46.  
  47. static long gp1;
  48. static long gp2;
  49.  
  50. #define min(a,b) (((a) < (b)) ? (a) : (b))
  51. #define max(a,b) (((a) > (b)) ? (a) : (b))
  52.  
  53. pascal OSErr SetDialogDefaultItem (    DialogPtr    theDialog,
  54.                                     short        newItem)
  55.     = {0x303c,0x0304,0xAA68};
  56.  
  57. void raiseRect (Rect theRect)
  58. {
  59.     ForeColor(whiteColor);
  60.     MoveTo(theRect.left,theRect.bottom);
  61.     LineTo(theRect.left,theRect.top);
  62.     LineTo(theRect.right,theRect.top);
  63.     ForeColor(blackColor);
  64.     LineTo(theRect.right,theRect.bottom);
  65.     LineTo(theRect.left,theRect.bottom);
  66. }
  67.  
  68. void groundRect (Rect theRect)
  69. {
  70.     ForeColor(whiteColor);
  71.     MoveTo(theRect.right,theRect.top);
  72.     LineTo(theRect.right,theRect.bottom);
  73.     LineTo(theRect.left,theRect.bottom);
  74.     ForeColor(blackColor);
  75.     LineTo(theRect.left,theRect.top);
  76.     LineTo(theRect.right,theRect.top);
  77. }
  78.  
  79. void drawSlider (    Rect    theRect,
  80.                     long    theValue)
  81. {
  82. short    iWidth;
  83. Str255    s;
  84.  
  85.     groundRect(theRect);
  86.     theRect.left += 1;
  87.     theRect.top += 1;
  88.     {
  89.     Pattern    myPat = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  90.     iWidth = theRect.left; // save left
  91.     theRect.left = theRect.left + (((theRect.right - theRect.left) * theValue) / 100);
  92.     EraseRect(&theRect);
  93.     theRect.right = theRect.left;
  94.     theRect.left = iWidth;
  95.     ForeColor(greenColor);
  96.     FillRect(&theRect,&myPat);
  97.     }
  98.     
  99.     ForeColor(blackColor);
  100.     NumToString(theValue, s);
  101.     TextFont(geneva);
  102.     TextSize(9);
  103.     SetRect(&theRect,theRect.left - 20,theRect.top,theRect.left - 1,theRect.bottom - 4);
  104.     EraseRect(&theRect);
  105.     iWidth = TextWidth(&s[1],0,s[0]);
  106.     MoveTo(theRect.right - iWidth - 2,theRect.bottom);
  107.     DrawString(s);
  108.     TextFont(systemFont);
  109.     TextSize(12);
  110. }
  111.  
  112. pascal void xRectProc (WindowPtr    theWindow,
  113.                         short        theItem)
  114. {
  115. short    iType;
  116. Handle    iHandle;
  117. Rect    iRect;
  118.  
  119.     GetDItem(theWindow,theItem,&iType,&iHandle,&iRect);
  120.     raiseRect( iRect);
  121. }
  122.  
  123. pascal void sliderProc (WindowPtr    theWindow,
  124.                         short        theItem)
  125. {
  126. short    iType;
  127. Handle    iHandle;
  128. Rect    iRect;
  129. long    v;
  130.  
  131.     long oldA4 = SetUpA4 ();
  132.  
  133.     if (theItem == slider1) v = gp1;
  134.     else v = gp2;
  135.  
  136.     GetDItem(theWindow,theItem,&iType,&iHandle,&iRect);
  137.     drawSlider( iRect, v);
  138.  
  139.     RestoreA4(oldA4);
  140. }
  141.  
  142. GDHandle    TheGDevice:0xCC8;
  143.  
  144. void AutoPosition( DialogPtr aDia)
  145. {
  146.     Point    Position, mouse;
  147.     Rect    ViewRect;
  148.     short    XSize = (aDia->portRect.right - aDia->portRect.left), YSize = (aDia->portRect.bottom - aDia->portRect.top);
  149.  
  150.  
  151.     GetMouse( &mouse);
  152.     LocalToGlobal( &mouse);
  153.  
  154.     SetRect( &ViewRect, (*TheGDevice)->gdRect.left + 8, (*TheGDevice)->gdRect.top + 43,
  155.                         (*TheGDevice)->gdRect.right - 8, (*TheGDevice)->gdRect.bottom - 8);
  156.  
  157.     Position.h = mouse.h - XSize/2;
  158.     if( Position.h + XSize >= ViewRect.right) Position.h = ViewRect.right - XSize;
  159.     else if( Position.h <= ViewRect.left) Position.h = ViewRect.left;
  160.  
  161.     Position.v = mouse.v - YSize/2;
  162.     if( Position.v + YSize >= ViewRect.bottom) Position.v = ViewRect.bottom - YSize;
  163.     else if( Position.v <= ViewRect.top) Position.v = ViewRect.top;
  164.  
  165.     MoveWindow( aDia, Position.h, Position.v, false);
  166.  
  167.     ShowWindow( aDia);
  168. }
  169.  
  170.  
  171. Boolean getParams ( short dlgID, Str255 s1, Str255 s2, PPInfoPlug *thePPInfoPlug)
  172. {
  173. DialogPtr    theDialog;
  174. Boolean        theResult = false;
  175.  
  176.     theDialog = GetNewDialog(dlgID,nil,(WindowPtr)-1);
  177.     if (theDialog) {
  178.         short    iType, itemHit;
  179.         Handle    iHandle;
  180.         Rect    iRect;
  181.         
  182.         SetPort( theDialog);
  183.         AutoPosition( theDialog);
  184.         GetDItem(theDialog,sname1,&iType,&iHandle,&iRect);
  185.         SetIText(iHandle,s1);
  186.         GetDItem(theDialog,sname2,&iType,&iHandle,&iRect);
  187.         SetIText(iHandle,s2);
  188.         GetDItem(theDialog,slider1,&iType,&iHandle,&iRect);
  189.         SetDItem(theDialog,slider1,iType,(Handle)sliderProc,&iRect);
  190.         GetDItem(theDialog,slider2,&iType,&iHandle,&iRect);
  191.         SetDItem(theDialog,slider2,iType,(Handle)sliderProc,&iRect);
  192.         GetDItem(theDialog,enclosure,&iType,&iHandle,&iRect);
  193.         SetDItem(theDialog,enclosure,iType,(Handle)xRectProc,&iRect);
  194.  
  195.         do {
  196.             ModalDialog( (ModalFilterProcPtr) thePPInfoPlug->MyDlgFilterUPP, &itemHit);
  197.             if ((itemHit == slider1) || (itemHit == slider2))
  198.             {    //track slider
  199.                 GrafPtr    savePort;
  200.                 Point    newp, oldp = { 0, 0};
  201.                 GetPort(&savePort);
  202.                 SetPort(theDialog);
  203.                 GetDItem(theDialog,itemHit,&iType,&iHandle,&iRect);
  204.                 while(WaitMouseUp()) {
  205.                     GetMouse(&newp);
  206.                     if (DeltaPoint(oldp,newp) & 0xFFFF) {
  207.                         long newVal = min( 100, max( 0, ((newp.h - iRect.left) * 100) / (iRect.right - iRect.left)));
  208.                         if (itemHit == slider1) gp1 = newVal;
  209.                         else gp2 = newVal;
  210.                         drawSlider( iRect, newVal);
  211.                         oldp = newp;
  212.                     }
  213.                 }
  214.                 SetPort(savePort);
  215.             }
  216.         } while ((itemHit != ok) && (itemHit != cancel));
  217.         if (itemHit == ok) {
  218.             theResult = true;
  219.         }
  220.         DisposDialog(theDialog);
  221.     }
  222.     return theResult;
  223. }
  224.  
  225. void alertUser ( short errString)
  226. {
  227. Str255    s;
  228.     GetIndString(s,5010,errString);
  229.     ParamText(s,nil,nil,nil);
  230.     StopAlert(5011,nil);
  231. }
  232.  
  233. OSErr main(     sData                    *theData,
  234.                 long                    SelectionStart,
  235.                 long                    SelectionEnd,
  236.                 PPInfoPlug                *thePPInfoPlug)
  237. {
  238.     long    oldA4, scrapOffset;
  239.     Handle    aHandle;
  240.  
  241.     oldA4 = SetCurrentA4();
  242.     RememberA4();
  243.     aHandle = nil;
  244.     if (GetScrap(aHandle,soundListRsrc,&scrapOffset) > 0) {
  245.         Str255    s1, s2 = "\pUntitled";
  246.  
  247.         aHandle = NewHandle(0);
  248.         s1[0] = strlen(theData->name);
  249.         BlockMove(theData->name,&s1[1],s1[0]);
  250.         if (GetScrap(aHandle,'STR ',&scrapOffset) > 0)
  251.             BlockMove(*aHandle,&s2,**aHandle + 1);
  252.         
  253.         gp1 = 50;
  254.         gp2 = 50;
  255.  
  256.         if (getParams (5010, s1, s2, thePPInfoPlug)) {
  257.             long    i, length1, length2, resultLength,
  258.                     temp1, temp2;
  259.             Ptr        clipPtr, resultPtr;
  260.  
  261.             GetScrap(aHandle,soundListRsrc,&scrapOffset);    //get the sound
  262.             HLockHi(aHandle);
  263.             
  264.             clipPtr = *aHandle;
  265.             i = *(shortPtr)clipPtr;
  266.             clipPtr += 4;
  267.             if ((i == 1) || (i == 2)) {
  268.                 if ((i == 2) || (*(shortPtr)clipPtr == sampledSynth)) {
  269.                     Ptr        worgPtr, wclipPtr, wresultPtr;
  270.                     long    temp, peak = 0;
  271.  
  272.                     if (i == 1) {
  273.                         clipPtr += 20;
  274.                     } else  clipPtr += 18;
  275.                     length2 = *(longPtr)clipPtr;    // sample length
  276.                     clipPtr += 18;                    // points to sample data
  277.     
  278.                     length1 = theData->size - SelectionStart;
  279.                     
  280.                     resultLength = SelectionStart + max( length1, length2);
  281.                     resultPtr = NewPtr(resultLength);
  282.  
  283.                     worgPtr = theData->data; wclipPtr = clipPtr;
  284.                     for( i = 0; i < SelectionStart; i++) // first pass to get max value.
  285.                     {
  286.                         temp1 = *worgPtr++;
  287.                         peak = max( peak, labs( gp1 * temp1));
  288.                     }
  289.                     for( i = 0; i < (resultLength - SelectionStart); i++)
  290.                     {
  291.                         if (i < length1) {
  292.                             temp1 = *worgPtr;
  293.                         } else temp1 = 0;
  294.                         if (i < length2) {
  295.                             temp2 = (*wclipPtr & 0xFF) - 0x80;
  296.                         } else temp2 = 0;
  297.                         
  298.                         peak = max( peak, labs((gp1 * temp1) + (gp2 * temp2)));
  299.                             
  300.                         worgPtr++;
  301.                         wclipPtr++;
  302.                     }
  303.                     
  304.                     peak = ((long)0x80 * 0x10000) / peak;
  305.                     
  306.                     worgPtr = theData->data; wclipPtr = clipPtr - SelectionStart; wresultPtr = resultPtr;
  307.                     for( i = 0; i < resultLength; i++) // one more time, all together, now !!!
  308.                     {
  309.                         if (i < theData->size) {
  310.                             temp1 = *worgPtr;
  311.                         } else temp1 = 0;
  312.                         if ((i >= SelectionStart) && (i < (length2 + SelectionStart))) {
  313.                             temp2 = (*wclipPtr & 0xFF) - 0x80;
  314.                         } else temp2 = 0;
  315.                         
  316.                         temp = (gp1 * temp1) + (gp2 * temp2);
  317.                         temp = (peak * temp) / 0x10000;
  318.                             
  319.                         if( temp >= 127) temp = 127;    // overflow ?
  320.                         else if( temp <= -128 ) temp = -128;
  321.  
  322.                         *wresultPtr = temp;
  323.                         worgPtr++;
  324.                         wclipPtr++;
  325.                         wresultPtr++;
  326.                     }
  327.                     
  328.                     DisposPtr(theData->data);            //all done
  329.                     theData->data = resultPtr;            //now switch
  330.                     theData->size = resultLength;        //Instrument Ptr
  331.                 
  332.                 } else alertUser (3);
  333.             } else alertUser (2);
  334.             
  335.             HUnlock(aHandle);
  336.         
  337.         }
  338.         
  339.         DisposHandle(aHandle);
  340.         
  341.     } else alertUser (1);
  342.  
  343.     SetA4(oldA4);
  344.     return noErr;
  345. }